﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ApplicationBlocks.Data;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using WP09S03_OfficeTracking.DAL;

namespace WP09S03_OfficeTracking.Controller
{

    class EmployeController:ParentClass.ParentController 
    {

        private String HashAlgorithm = "MD5";
        private byte[] SaltBytes;
        
        private DSEmployee DS;
        private DAL.DSEmployeeTableAdapters.EmployeeTableAdapter DTA;
        private DAL.DSEmployeeTableAdapters.UserTableAdapter DTAUser;

        public EmployeController() : base()
        {
            SaltBytes = Encoding.UTF8.GetBytes("S03");

            DTA = new DAL.DSEmployeeTableAdapters.EmployeeTableAdapter();
            DS = new DSEmployee();
            DTA.Fill(DS.Employee);  

            DTAUser = new DAL.DSEmployeeTableAdapters.UserTableAdapter();
            DTAUser.Fill(DS.User);
        }

        private byte[] getPasswordBytes(string password)
        {
            string HashValue = SimpleHash.ComputeHash(password, HashAlgorithm, SaltBytes);            
            return Convert.FromBase64String(HashValue); 
        }


        public bool ValidateLogin(String UserID, String Password) {

           DSEmployee.UserDataTable table = DTAUser.GetDataByNameAndPassword(UserID, getPasswordBytes(Password));
           if (table != null)
           {
               if (table.Rows.Count > 0)
                   return true;

           }
           return false;
        }

        public bool ChangePassword(String UserID, String OldPassword, String NewPassword) {

            DSEmployee.UserDataTable table = DTAUser.GetDataByNameAndPassword(UserID, getPasswordBytes(OldPassword));
            if (table != null)
            {
                if (table.Rows.Count == 0)
                    throw new Exception("Invalid current password input");

                DTAUser.Update(getPasswordBytes(NewPassword), UserID, getPasswordBytes(OldPassword)); 
                
                return true;
            }
            return false;
        }


        public DAL.DSEmployee GetEmployee() {

            DAL.DSEmployeeTableAdapters.EmployeeTableAdapter da = new DAL.DSEmployeeTableAdapters.EmployeeTableAdapter();

            DSEmployee ds = new DSEmployee();
           
            da.Fill(ds.Employee);

            return ds;
            
        }

        public int GetEmployeesByIDName(DataGridView control, string id, string name)
        {
            DAL.DSEmployee.EmployeeDataTable table = null;
            int ret = 0;

            id = id.Trim();
            name =name.Trim();
            //Calls using like
            table = DTA.GetDataByIDAndName(id, name);
            //table = DTA.GetDataAll();
            if (table != null)
            {
                control.DataSource = table;
                ret = table.Rows.Count;
            }
            return ret;
        }

        public DSEmployee.EmployeeDataTable GetEmployeesByID(string id)
        {
            return DTA.GetDataByIDAndName(id, "");            
        }


        public bool DeleteEmployee(string id, string name, string number, string email)
        {
 
            //check if employee is user
            DAL.DSEmployeeTableAdapters.UserDataTableTableAdapter DTAUserData = new DAL.DSEmployeeTableAdapters.UserDataTableTableAdapter();
            DAL.DSEmployee.UserDataTableDataTable table = null;

            table = DTAUserData.GetUserData();

            foreach (DataRow r in table)
            {
                if (r["EmployeeID"].ToString() == id)
                {
                    throw new Exception("Delete failed. Employee is a registered user.");
                }
            }

            //check if employee has outstanding transaction
            DAL.DSReport ds = new DAL.DSReport();
            DAL.DSReportTableAdapters.OverdueItemsTableAdapter DTAItems = new DAL.DSReportTableAdapters.OverdueItemsTableAdapter();

            //DAL.DSReport.OverdueItemsDataTable itemTable = null;
            //itemTable = DTAItems.GetBorrowedItems();
            ds.EnforceConstraints = false;
            DTAItems.FillBorrowedItems(ds.OverdueItems);
            foreach (DataRow r in ds.OverdueItems.Rows)
            {
                if (r["EmployeeID"].ToString() == id)
                {
                    throw new Exception("Delete failed. Employee has unreturned items.");
                }
            }

            
            try
            {
                DTA.Update(id, name, number, email, false, id, name, number, email, true);

                //DTA.Delete(id, name, number, email);
            }
            catch (SqlException e)
            {
                e.GetType();
                string msg = "Unable to delete employee." +
                             "Possible outstanding transactions or employee is a registered user";
                throw new Exception(msg);
            }
            return true;
        }

        public bool UpdateEmployee(string id, string name, string number, string email,
                                   string orig_id, string orig_name, string orig_number, 
                                   string orig_mail)
        {

            id = id.Trim();
            name = name.Trim();
            number = number.Trim();
            email = email.Trim();

            orig_id = orig_id.Trim();
            orig_name = orig_name.Trim();
            orig_number = orig_number.Trim();
            orig_mail =  orig_mail.Trim();
            
            if (id == orig_id && name == orig_name && number == orig_number && email == orig_mail)
            {
                throw new Exception("No changes detected.");
            }
            if (validateInfo(id, name, number, email) == true)
            {
                DTA.Update(id, name, number, email, true, orig_id, orig_name, orig_number, orig_mail, true);
                
                return true;
            }
            return false;
        }

        public bool AddEmployee(string id, string name, string number, string email)
        {
            id = id.Trim();
            name = name.Trim();
            number = number.Trim();
            email.Trim();

            if (validateInfo(id, name, number, email) == true)
            {

                try
                {
                    DTA.Insert(id, name, number, email, true);
                    return true;
                }
                catch (SqlException e)
                {
                    e.GetType();
                    throw new Exception("Employee ID already exists.");
                }
            }
            return false;
        }

        public string GetEmployeeEmail(string id)
        {
            DAL.DSEmployee.EmployeeDataTable table = null;

            id = id.Trim();
            //Calls using like
            table = DTA.GetDataByIDAndName(id, "%");

            if (table != null)
            {
                if (table.Rows.Count == 1)
                    return table.Rows[0]["Email"].ToString();
                
            }
            throw new Exception("Employee ID " + id + " not found.");

        }

        private bool validateInfo(string id, string name, string number, string email)
        {
            if (id.Length == 0)
                throw new Exception("Invalid ID.");

            if (name.Length == 0)
                throw new Exception("Invalid Name.");

            if (number.Contains("_") || number.Length < 9)
                throw new Exception("Invalid Contact Number.");

            if (email.Contains("@") == false)
                throw new Exception("Invalid Email.");

            return true;
        }

        public void EditUser(string id, string oldPassword, string newPassword)
        {
            id = id.Trim();
            oldPassword = oldPassword.Trim();
            newPassword = newPassword.Trim();

            DAL.DSEmployee.EmployeeDataTable table = null;
            table = DTA.GetData(); // GetDataByID(id);
            if (table == null)
                throw new Exception("User ID does not exists.");

            DAL.DSEmployee.EmployeeRow row = table.FindByEmployeeID(id);
            if (row == null)
                throw new Exception("User ID does not exists.");               

            DAL.DSEmployee.UserDataTable userTable = null;
            userTable = DTAUser.GetData();

            if (userTable == null)
                throw new Exception("User record not found.");

            validatePassword(newPassword);
            
            if (userTable.Rows.Count == 0)
            {
                //just add
                DTAUser.Insert(id, getPasswordBytes(newPassword));
            }
            else
            {

                if (oldPassword.Length == 0)
                    throw new Exception("Invalid current password input.");

                if (oldPassword == newPassword)
                    throw new Exception("Password entered is not new.");

                if (ChangePassword(id, oldPassword, newPassword) == false )
                    throw new Exception("Password change failed.");        
            }
                         
        }

 
        public void GetAllUsers(DataGridView control)
        {
            DAL.DSEmployeeTableAdapters.UserDataTableTableAdapter DTAUserData = new DAL.DSEmployeeTableAdapters.UserDataTableTableAdapter();
            DAL.DSEmployee.UserDataTableDataTable table = null;
            
            table = DTAUserData.GetUserData();
    
            if (table != null)
            {
                control.DataSource = table;
            }
            else
            {
                throw new Exception("User table not found.");
            }
            
        }

        public void AddUser(string id, string newPassword)
        {
            id = id.Trim();
            newPassword = newPassword.Trim();

            DAL.DSEmployee.EmployeeDataTable table = null;
            table = DTA.GetData(); 
            if (table == null)
                throw new Exception("User ID does not exists.");

            DAL.DSEmployee.EmployeeRow row = table.FindByEmployeeID(id);
            if (row == null)
                throw new Exception("User ID does not exists.");

            DAL.DSEmployee.UserDataTable userTable = null;
            userTable = DTAUser.GetData();

            if (userTable == null)
                throw new Exception("User record not found.");

            validatePassword(newPassword);

            DTAUser.Insert(id, getPasswordBytes(newPassword));

        }

        private void validatePassword(string password)
        {
            if (password.Contains(" ")) 
                throw new Exception("Invalid password characters.");

            if (password.Length < 6 || password.Length > 10)
                throw new Exception("Invalid password content. Must be 6 to 10 characters");

        }

        public void DeleteUser(string id)
        {
            DAL.DSEmployee.UserDataTable table = null;

            table = DTAUser.GetData();
            if (table != null)
            {
                if (table.Rows.Count <= 1)
                    throw new Exception("At least 1 User must remain.");
            }
                        
            DTAUser.DeleteUserByID(id);
        }


        public int RemindEmployeesOfOverdueItems()
        {
            int num = 0;

            DAL.DSReport ds = new DAL.DSReport();
            DAL.DSReportTableAdapters.OverdueItemsTableAdapter DTAItems = new DAL.DSReportTableAdapters.OverdueItemsTableAdapter();          
            ds.EnforceConstraints = false;
            DTAItems.FillOverdueItems(ds.OverdueItems);
 
            foreach (DataRow r in ds.OverdueItems.Rows)
            {
                string email = r["Email"].ToString();
                string name = r["EmployeeName"].ToString();
                string id = r["ItemID"].ToString();
                string serial = r["SerialNo"].ToString();
                string item = r["ItemName"].ToString();
                string loan = r["UsedStartTime"].ToString();
                string due = r["UsedEndTime"].ToString();
                string subject = "Reminder: Please return item.";
                string body = "<p>Dear " + name + ",</p><p style='margin-left:40px'>This is to remind you to return the following item:</p>";
                body += "<p style='margin-left:40px'>Item ID: " + id + "</p>";
                body += "<p style='margin-left:40px'>Item Name: " + item + "</p>";
                body += "<p style='margin-left:40px'>Serial No: " + serial + "</p>";
                body += "<p style='margin-left:40px'>Loan Date: " + loan + "</p>";
                body += "<p style='margin-left:40px'>Due Date: " + due + "</p>";
                body += "<p style='margin-left:40px'>------------------------------------------------------</p>";
                body += "<p style='margin-left:40px'>This is a system generated email, please do not reply.</p>";


                if (this.EmailSend(email, subject, body))
                    num++;
            }
            return num;
        }



    }


   
    

}
